import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {List} from 'linqts';
import {DatePipe} from '@angular/common';
import {DataSourceService} from '../../../../service/data-source/data-source.service';
import {ITdDataTableColumn, TdDialogService} from '@covalent/core';
//报警级别、类别数据模型
import {FaultLevel} from '../../../../entity/fault-level.model';
import {FaultData} from '../../../../entity/fault-data';
import {AlarmCategory} from '../../../../entity/alarm-category.model';

import {FaultLevelService} from '../../../../service/fault_level.service';
import {AlarmCategoryService} from '../../../../service/alarm-category.service';
// import { AlarmListComponent } from "../../../alarm/alarm-search/alarm-list/alarm-list.component";
import {NzMessageService} from 'ng-zorro-antd';
import {ApplicationService} from '../../../../service/application.service';
import {InterceptorService} from '../../../../service/interceptor/interceptor-service';
//列表数据模型
import {AlarmSearchData, FaultCount} from '../../../../entity/alarm/alarm-search.data';
import {TurbComponent} from '../../../../entity/turbcomponent.model';
import {TurbcomponentService} from '../../../../service/turbcomponent.service';

@Component({
  selector: 'app-inverter-alarm-list',
  templateUrl: './inverter-alarm-list.component.html',
  styleUrls: ['./inverter-alarm-list.component.css']
})
export class InverterAlarmListComponent implements OnInit {
  /**
   * 数据源服务
   *
   * @private
   * @type {DataSourceService}
   * @memberof TurbineListComponent
   */
  private dataSource: DataSourceService;
  /**
   * 报警类别数据集合
   *
   * @type @memberof AlarmListComponent
   */
  public alarmCategoryDatas: AlarmSearchData[] = [];

  /**
   * 故障统计数据集合
   * @type @memberof AlarmListComponent
   */
  public faultCountData: FaultCount[] = [];
  public faultCountList: FaultCount[] = [];
  public pages: number;
  private h = 1000 * 3600;
  /**
   * 故障等级数据集合
   *
   * @type @memberof AlarmListComponent
   */
  public faultLevels: FaultLevel[] = [];

  //故障类别数据集合
  public turbComponents: TurbComponent[] = [];
  public active: number = 0;
  //列表数据集合
  private faultDatas: FaultData[] = [];
  faultData1: FaultData[] = [];
  faultData2: FaultData[] = [];

  // 统计数据
  faultData3: FaultCount[] = [];
  faultData4: FaultCount[] = [];
  @ViewChild('alarmTable', {static: true})
  alarmTable: ElementRef;
  row: number;

  @ViewChild('countTable', {static: true})
  countTable: ElementRef;
  rowC: number;
  /**
   * 表头
   *
   * @type {number}@memberof AlarmListComponent
   */
  public columns: ITdDataTableColumn[] = [
    {name: 'faultCode', label: '故障码'},
    {name: 'turbComponentName', label: '故障类别',},
    {name: 'faultLevelName', label: '故障等级'},
    {name: 'faultDesc', label: '故障内容'},
    {name: 'faultTime', label: '时间'},
  ];
  cars: AlarmSearchData;

  constructor(
    private http: InterceptorService,
    private datePipe: DatePipe,
    private _dialogService: TdDialogService,
    private alarmCategoryService: AlarmCategoryService,
    private faultLevelService: FaultLevelService,
    private turbcomponentService: TurbcomponentService,
    private _message: NzMessageService,
    private application: ApplicationService,
  ) {
  }

  ngOnInit() {
    Promise.all([
      this.alarmCategoryService.getAlarmCategorys(),
      this.faultLevelService.getFaultLevelsWithSound(),
      this.turbcomponentService.getTurbComponents()])
      .then(res => {
        if (res[1]) {
          this.faultLevels.push(...res[1]);
        }
        ;
        if (res[2]) {
          this.turbComponents.push(...res[2])
        }
        ;
        this.initData(res[0]);
      })
      .catch(error => {
        if (this.application.appConfigData.isShowErr) {
          this._message.info('报警数据' + error, {nzDuration: 3000});
        }

        //console.log("app-alarm-lamp has error", error);
      });
  }

  ngOnDestroy(): void {
    if (this.dataSource != null)
      this.dataSource.dispose();
  }

  initData(categorys: AlarmCategory[]) {
    if (!categorys) return false;
    categorys.forEach((category, index) => {
      let alarmCategoryData = {
        alarmCategoryId: category.alarmCategoryId,
        alarmCategoryName: category.alarmCategoryName,
        faultDatas: [],
        faultTableData: [],
        faultCounts: [],
        faultCountData: [],
        isChecked: index === 0 ? true : false,
        faultLevelTotals: this.faultLevels,
        turbComponentTotals: this.turbComponents,
        faultLength: 0
      };

      this.alarmCategoryDatas.push(alarmCategoryData);
    });
  }

  public onAlarmCategoryClick(alarmCategpry: AlarmSearchData) {
    alarmCategpry.isChecked = true;
    let alarmCategprys = this.alarmCategoryDatas.filter(o => o.alarmCategoryId != alarmCategpry.alarmCategoryId);
    if (alarmCategprys && alarmCategprys.length > 0) {
      alarmCategprys.map(o => o.isChecked = false);
    }
  }

  datasource: AlarmSearchData[];

  totalRecords: number;

  upData(deviceIds: number[], startTime: Date, endTime: Date) {
    let faultDatas = [];
    this.alarmCategoryDatas.forEach(o => o.faultDatas = []);
    this.alarmCategoryDatas.forEach(o => o.faultCounts = []);

    if (this.dataSource != null) {
      this.dataSource.dispose();
    }

    this.dataSource = new DataSourceService(this.http, this.datePipe)
    this.dataSource
      .history
      .getTurbineFaults(deviceIds, startTime, endTime)
      .then(res => {
        if (!res) {
          return false;
        }
        this.faultDatas = [...res];
        faultDatas.push(...res);
        this.alarmCategoryDatas.forEach((category, i) => {
          category.faultDatas = [];
          category.faultCounts = [];

          let faultData: FaultData[] = [...faultDatas.filter(o => o.alarmCategoryId == category.alarmCategoryId)];
          const faultsAllCount = [...faultData];
          category.faultLength = faultData.length;
          if (i) {
            this.faultData2 = [...faultData];
          } else {
            this.faultData1 = [...faultData];
          }
          let faults: FaultData[] = faultData.slice(0, 10);

          category.faultDatas = [...faults];

          // 按code统计报警数量
          const counts: FaultCount[] = [];
          let faultCountsData: FaultCount[] = [];
          const list = new List(faultsAllCount);
          // 按code分组
          const groups = list.GroupBy(grouper => grouper.faultCode, mapper => mapper);
          const codes = Object.getOwnPropertyNames(groups);
          codes.forEach(code => {
            const codeList = new List<FaultData>(Object.getOwnPropertyDescriptor(groups, code).value);
            const codeListArr = new List<FaultData>(Object.getOwnPropertyDescriptor(groups, code).value).ToArray();
            const timeWork = codeList.Sum(o => new Date(o.faultEndTime).getTime() - new Date(o.faultTime).getTime());
            const faultCountData: FaultCount = {
              faultCode: code,
              farmName: codeListArr[0].farmName,
              deviceName: codeListArr[0].deviceName,
              faultDesc: codeListArr[0].faultDesc,
              faultLevelColor: codeListArr[0].faultLevelColor,
              faultWorkTime: Number((timeWork / this.h).toFixed(2)),
              faultCount: codeList.Count()
            }
            counts.push(faultCountData)
          })
          faultCountsData = [...counts]
          category.faultCountLength = faultCountsData.length;
          if (i) {
            this.faultData3 = [...faultCountsData];
          } else {
            this.faultData4 = [...faultCountsData];
          }
          const faultsC: FaultCount[] = faultCountsData.slice(0, 10);
          category.faultCounts = [...faultsC];
        });
        // this.row = Math.floor((this.alarmTable.nativeElement.clientHeight - 40) / 30);
        if (this.active === 0) {
          this.row = Math.floor((this.alarmTable.nativeElement.clientHeight - 40) / 30);
          this.rowC = Math.floor((this.alarmTable.nativeElement.clientHeight - 40) / 30);
        } else {
          this.row = Math.floor((this.countTable.nativeElement.clientHeight - 40) / 30);
          this.rowC = Math.floor((this.countTable.nativeElement.clientHeight - 40) / 30);
        }
      })
      .catch(error => {
        if (this.application.appConfigData.isShowErr) {
          this._message.info('历史报警数据' + error, {nzDuration: 3000});
        }

        //console.log("app-alarm-search has error", error);
      });
  }

  loadData(event: any, index: number) {
    setTimeout(() => {
      if (index) {
        this.alarmCategoryDatas[index].faultDatas = this.faultData2.slice(event.first, (event.first + event.rows));
      } else {
        this.alarmCategoryDatas[index].faultDatas = this.faultData1.slice(event.first, (event.first + event.rows));
      }

    }, 250);

  }

  loadCountData(event: any, index: number) {
    setTimeout(() => {
      if (index) {
        this.alarmCategoryDatas[index].faultCounts = this.faultData3.slice(event.first, (event.first + event.rows));
      } else {
        this.alarmCategoryDatas[index].faultCounts = this.faultData4.slice(event.first, (event.first + event.rows));
      }

    }, 250);
  }

  onClickHeader(n: number) {
    this.active = n;
  }

  onResize(ev) {
    // this.row = Math.floor((this.alarmTable.nativeElement.clientHeight - 40) / 30);
    if (this.active === 0) {
      this.row = Math.floor((this.alarmTable.nativeElement.clientHeight - 40) / 30);
      this.rowC = Math.floor((this.alarmTable.nativeElement.clientHeight - 40) / 30);
    } else {
      this.row = Math.floor((this.countTable.nativeElement.clientHeight - 40) / 30);
      this.rowC = Math.floor((this.countTable.nativeElement.clientHeight - 40) / 30);
    }
  }
}
